package top.eggcode.modules.user.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.eggcode.common.exception.ApplicationException;
import top.eggcode.component.redis.RedisUnit;
import top.eggcode.modules.user.model.AccountEntity;
import top.eggcode.modules.user.model.UserEntity;
import top.eggcode.modules.user.model.UserQuery;
import top.eggcode.modules.user.store.AccountRepository;
import top.eggcode.modules.user.store.AccountStore;
import top.eggcode.modules.user.store.UserStore;
import top.eggcode.base.BaseServiceImpl;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * Title: 账户服务实现
 * Description: TODO
 * Date: 2021/3/27 12:44
 *
 * @author JiaQi Ding
 * @version 1.0
 */
@Slf4j
@Transactional(rollbackFor = Exception.class)
@Service
@RequiredArgsConstructor
public class AccountService extends BaseServiceImpl<AccountEntity> {

    private final AccountRepository selfRepository;

    private final RedisUnit buffer;

    private final UserStore userStore;

    private final AccountStore accountStore;

    public Page<AccountEntity> page(UserQuery query, Pageable pagination) {

        return selfRepository.listPage(query, pagination);
    }


    public Optional<AccountEntity> query(String username, String password) {
        List<AccountEntity> accountList = selfRepository.findByUsernameAndPassword(username, password);

        if (accountList.size() == 1) {
            return Optional.of(accountList.get(0));
        } else if (accountList.size() > 1) {
            throw new ApplicationException("查询账户出现异常，账户重复");
        }
        return Optional.empty();
    }

    public Optional<AccountEntity> findByUsername(String username) {
        Objects.requireNonNull(username);
        String cacheKey = "account::" + username;
        // 查找缓存
        if (buffer.hasKey(cacheKey)) {
            return Optional.ofNullable(buffer.getBean(cacheKey, AccountEntity.class));
        }
        List<AccountEntity> accountList = selfRepository.findByUsername(username);

        AccountEntity account = super.mostOne(accountList);
        if (account != null) {
            // 添加缓存
            buffer.setBean(cacheKey, accountList.get(0), 600);
        }
        return Optional.ofNullable(account);
    }


    /**
     * entity 的空值也会同步到数据库
     *
     * @param entity 对象信息
     */
    @Override
    public void put(AccountEntity entity) {
        if (entity.getUsername() == null) {
            throw new ApplicationException("用户名为空");
        }
        Optional<AccountEntity> box = this.findByUsername(entity.getUsername());

        // 如果账户已经存在，则更新覆盖
        if (box.isPresent()) {
            AccountEntity account = box.get();
            account.setPassword(entity.getPassword());
            account.setPassword(entity.getPassword());
            account.setStatus(entity.getStatus());
            account.setTier(entity.getTier());
            account.markUpdated();
            // 更新到数据库
            this.update(account);

        } else {
            super.add(entity);
        }
    }

    public Optional<AccountEntity> findByUserId(String userId) {
        return Optional.ofNullable(selfRepository.findByUserId(userId));
    }

    /**
     * 注册账户
     *
     * @param entity 实体
     * @return 执行结果
     */
    public void register(AccountEntity entity) {

        // 初始化一个用户信息
        UserEntity user = new UserEntity();
        user.markCreated();
        userStore.save(user);

        Optional<AccountEntity> box = accountStore.getByUsername(entity.getUsername());
        if (!box.isPresent()) {
            // 绑定用户
            entity.setUserId(user.getId());
            // 标记正常状态
            entity.setStatus((short) 1);
            accountStore.save(entity);
        } else {
            throw new ApplicationException("账号已经存在，无法继续注册，username：" + entity.getUsername());
        }


    }
}
